#ifndef _BTRIEVE_H
#define _BTRIEVE_H

#include <EIC.h>
#include <vcl\dstring.h>
#define BTI_WIN_32 // Pour les prototypes Windows 32 bits
#pragma pack( 1)
#include "BtrConst.inc"
#include "BtrAPI.inc"
#pragma pack()

#ifdef _EICBTRV_BPL
  #define PACKAGE_EICBTRV __declspec( dllexport)
#else
  #define PACKAGE_EICBTRV __declspec( dllimport)
#endif


//*******************************************//
// Définition des codes d'opérations BTrieve //
//*******************************************//
#define  BTRV_Open          0
#define  BTRV_Close         1

#define  BTRV_Insert        2
#define  BTRV_Update        3
#define  BTRV_Delete        4

#define  BTRV_GetFirst     12
#define  BTRV_GetPrev       7
#define  BTRV_GetNext       6
#define  BTRV_GetLast      13

#define  BTRV_StepFirst    33
#define  BTRV_StepPrev     35
#define  BTRV_StepNext     24
#define  BTRV_StepLast     34

#define  BTRV_GetPos       22
#define  BTRV_GetDirect    23

#define  BTRV_GetEQ         5 /* Equal                 */
#define  BTRV_GetGT         8 /* Greater Than          */
#define  BTRV_GetGTEQ       9 /*    "     "   or Equal */
#define  BTRV_GetLT        10 /* Less Than             */
#define  BTRV_GetLTEQ      11 /*  "    "   or equal    */

#define  BTRV_Ver          26
#define  BTRV_Stat         15
#define  BTRV_Stop         25
#define  BTRV_Reset        28
#define  BTRV_Create       14
#define  BTRV_Extend       16

#define  BTRV_SetSystemDir 17
#define  BTRV_GetSystemDir 18

#define  BTRV_BeginTrans   19
#define  BTRV_EndTrans     20
#define  BTRV_AbortTrans   21

#define  BTRV_SetOwner     29
#define  BTRV_ClrOwner     30

#define  BTRV_CreatSupIndx 31
#define  BTRV_DropSupIndx  32

#define  BTRV_GetPrevExt   37
#define  BTRV_SetNextExt   36
#define  BTRV_StepPrevExt  39
#define  BTRV_StepNextExt  38
#define  BTRV_InsertExt    40

#define  BTRV_Unlock               27
#define  BTRV_SingleRecWaitLock   100 /* A ajouter à un autre code op */
#define  BTRV_SingleRecNoWaitLock 200 /* "    "    " "    "    "   "  */
#define  BTRV_NoWaitFileLock      200 /* "    "    " "    "    "   "  */
#define  BTRV_MultRecWaitLock     300 /* "    "    " "    "    "   "  */
#define  BTRV_MultRecNoWaitLock   400 /* "    "    " "    "    "   "  */


//************************************//
// Définition des versions de BTrieve //
//************************************//
enum BTRV_VERSION_ID {
  BTRV_VERSION_LOCAL_MKDE        = 0,
  BTRV_VERSION_REQUESTER         = 1,
  BTRV_VERSION_SERVER_BASED_MKDE = 2
 };


//***********************************************//
// Définition des modes d'ouverture d'un fichier //
//***********************************************//
enum BTRV_OPEN_MODE {
  BTRV_RW     = 0x00, /* Ouverture en lecture/écriture  normale   */
  BTRV_RWEXCL = 0xFC, /*     "      "         "        exclusive  */
  BTRV_R      = 0xFE  /*     "      " lecture seule               */
 };


//****************************************//
// Types utilisés pour l'opération Create //
//****************************************//
// Macro de calcul de la taille du champ f de la structure s
#define fieldsize( s, f) sizeof( ((s*)0)->f)

// Type de description d'une clé
extern "C" {
 #pragma pack( 1)
 typedef struct tagBTRV_KEY_SPEC {
   unsigned short nKeyPosition;     // Position clé >= 1  (1 + offsetof())
   unsigned short nKeyLength;       // Longueur clé       (fieldsize())
   unsigned short fKeyFlags;        // Une valeur KF_*
   unsigned long  dwNbKeysValues;   // Nombre de valeurs uniques de la clé (0L pour Create)
   unsigned char  cExtendedKeyType; // Une valeur EKF_*
   unsigned char  cNull;            // Valeur de clé nulle (toujours '\0') */
   unsigned short wReserved;        // Toujours 0
   unsigned char  cKeyNumber;       // N° de la clé (0 pour Create)
   unsigned char  cACSNumber;       // N° de l'ACS de tri (0 pour Create)
   } BTRV_KEY_SPEC;
 #pragma pack()
}

// Valeurs binaires combinables pour BTRV_KEY_SPEC.fKeyFlags
#define KF_DUPLICATE     0x0001
#define KF_MODIFIABLE    0x0002
#define KF_BINARY        0x0004
#define KF_NULL          0x0008
#define KF_SEGMENTED     0x0010
#define KF_ALT_COL_SEQ   0x0020
#define KF_DESCENDING    0x0040
#define KF_SUPPLEMENTAL  0x0080
#define KF_EXTENDED_TYPE 0x0100
#define KF_MANUAL        0x0200

#define KF_STANDARD_STRING 0x0000
#define KF_STANDARD_BINARY KF_BINARY

// Valeurs numériques pour BTRV_KEY_SPEC.cExtendedKeyType
#define EKT_NONE            ((unsigned char)0)
#define EKT_STRING          ((unsigned char)0)
#define EKT_INTEGER         ((unsigned char)1)
#define EKT_FLOAT           ((unsigned char)2)
#define EKT_DATE            ((unsigned char)3)
#define EKT_TIME            ((unsigned char)4)
#define EKT_DECIMAL         ((unsigned char)5)
#define EKT_MONEY           ((unsigned char)6)
#define EKT_LOGICAL         ((unsigned char)7)
#define EKT_NUMERIC         ((unsigned char)8)
#define EKT_BFLOAT          ((unsigned char)9)
#define EKT_L_STRING        ((unsigned char)10)
#define EKT_Z_STRING        ((unsigned char)11)
#define EKT_UNSIGNED_BINARY ((unsigned char)14)
#define EKT_AUTOINCREMENT   ((unsigned char)15)

// Type de description d'un fichier
 //*****************************************************************************
 //   ATTENTION POUR l'opération Create Redéfinir la structure avec le nombre de segments voulus
 //  Cause : Mauvaise affectation de [ ]
 //  Si c'est pas clair Voir Alex 8/10/99 (cf Impimmo)
 //*****************************************************************************
extern "C" {
 #pragma pack( 1)
 typedef struct tagBTRV_FILE_SPEC {
   unsigned short nRecordLength; // Taille d'un enregistrement
   unsigned short nPageSize;     // Taille d'une page (Cf. IDEAL.EXE)
   unsigned short nNbIndexes;    // Nombre de clés du fichier
   unsigned long  dwNbRecords;   // Nombre d'enregistrements dans le fichier (0L pour Create)
   unsigned short fFileFlags;    // Une valeur FF_*
   unsigned short wReserved;     // Toujours 0
   unsigned short nAllocation;   // Nb de pages inutilisées (Nb de pages à préallouer pour Create)
   BTRV_KEY_SPEC  KeysSpec[ ];  // Description des clés
   } BTRV_FILE_SPEC;
 #pragma pack()
}

// Macro de calcul de la taille d'une description d'un fichier avec n segments de clés
#define BTRV_SIZEOF( NB_KEY_SEGMENTS) ( sizeof( BTRV_FILE_SPEC) + ( (NB_KEY_SEGMENTS) * sizeof( BTRV_KEY_SPEC)))

// Valeurs binaires combinables pour BTRV_FILE_SPEC.fFileFlags
#define FF_NO_FLAG          0x0000
#define FF_VARIABLE_LENGTH  0x0001
#define FF_BLANK_TRUNCATION 0x0002
#define FF_PREALLOCATION    0x0004
#define FF_DATA_COMPRESSION 0x0008
#define FF_KEY_ONLY         0x0010
#define FF_10p_FREE_SPACE   0x0040
#define FF_20p_FREE_SPACE   0x0080
#define FF_30p_FREE_SPACE   ( FF_10p_FREE_SPACE | FF_20p_FREE_SPACE)


//***********************************//
// Définition de codes erreur usuels //
//***********************************//
#define BTRVERR_SUCCESS                    0
#define BTRVERR_INVALID_CODE_OP            1
#define BTRVERR_IO_ERROR                   2
#define BTRVERR_FILE_NOT_OPEN              3
#define BTRVERR_KEY_NOT_FOUND              4
#define BTRVERR_DUPLICATE_KEY              5
#define BTRVERR_INVALID_POSITION           8
#define BTRVERR_EOF                        9
#define BTRVERR_FILE_NOT_FOUND            12
#define BTRVERR_RECORD_MANAGER_INACTIVE   20
#define BTRVERR_DATA_BUFFER_LENGTH        22
#define BTRVERR_INVALID_RECOD_ADDRESS     43
#define BTRVERR_FILE_ALREADY_EXIST        59

enum ACTION_CREATE{
	ERROR_IF_FILE_EXIST = 0,
	OVERWRITE_IF_FILE_EXIST,
    NO_ERROR_NO_OVERWRITE_IF_FILE_EXIST
};

//****************************************//
// Définition de constantes particulières //
//****************************************//
// Identificateur de clé : indique qu'il ne faut pas changer de clé; cet
// ID de clé impose le passage d'un buffer de clé à NULL aux méthodes concernées
// (Les méthodes qui acceptent cette clé particulière la prenne comme valeur par défaut)
#define K_CURRENT 0xFF


class PACKAGE_EICBTRV CBtrvFile
{
 protected:
  static void* sm_pvDummy; // Pointeur sur 4 octets à 0 (utilisable pour les paramètres inutiles vers BTrieve
/*  #ifdef _DEBUG
   WORD dbgm_eLastKeyID; // Dernière clé utilisée dans un appel standard
  #endif*/
 private:
  AnsiString    m_strShortFileName; // Nom (court) du fichier
  unsigned char m_pos[ 128];        // Position dans le fichier BTrieve
  unsigned long m_nSizeOfRecord;    // Taille d'un enregistrement du fichier (0 si pas de fichier associé)
  inline bool  __fastcall GetIsOpened() const { return( m_nSizeOfRecord != 0);}
         DWORD __fastcall GetNbEnreg()  const;
  int __fastcall GetRecordCount();
  mutable unsigned int m_StatusErreur;
  static void __fastcall InitBtrv32();

 public:
  __property AnsiString ShortFileName = { read = m_strShortFileName};
  __property bool       IsOpened      = { read = GetIsOpened};
  __property DWORD      NbEnreg       = { read = GetNbEnreg};
  __property int RecordCount = {read = GetRecordCount};
  static BTRCALLFCT m_EicBtrCall;
  static void       __fastcall Stop();
  static void       __fastcall Reset(); /* Inclu Stop() */
  static AnsiString __fastcall GetVersion( enum BTRV_VERSION_ID eVersionMKDE = BTRV_VERSION_LOCAL_MKDE);
  static bool       __fastcall IsEmpty( EICTag tag, const AnsiString& strShortFileName);
  unsigned __cdecl Call( EICTag tag,
                         WORD   eOperation,
                         void*  pvDataBuffer,
                         void*  pvKeyBuffer,
                         WORD   eKeyID,
                         int    uNbErrCodes = 0, /* < 0 pour tous */
                         ...);
  void __fastcall ThrowUserError( EICTag   tag,
                                  WORD     eOperation,
                                  WORD     eKeyID,
                                  unsigned uErrCode) const;
    // Renvoi si le fichier a été nouvellement créé ou non
  bool __fastcall Create( EICTag                tag,
                          const AnsiString&     strNewShortFileName,
                          const BTRV_FILE_SPEC* pcfs,
                          size_t                nSizeOfFileSpec,
                          enum ACTION_CREATE    eAction = ERROR_IF_FILE_EXIST);
  bool __fastcall Open( EICTag              tag,
                        enum BTRV_OPEN_MODE eOpenMode,
                        size_t              nSizeOfRecord,
                        const AnsiString&   strShortFileName   = EmptyStr, // EmptyStr = précédent
                        bool                bNoErrorIfNotFound = false);
  void __fastcall Close( EICTag tag);
  void __fastcall Stat( EICTag tag,BTRV_FILE_SPEC* pcfs);
 //******************************************//
 // Opérations standard de parcours sans clé //
 //******************************************//
 // Retournent TRUE si l'opération a bien aboutie
//  bool __fastcall StepFirst( EICTag tag, void* pvBuffer);
  bool __fastcall StepNext(  EICTag tag, void* pvBuffer);
  void __fastcall DelCurrent( EICTag tag);
 //******************************************//
 // Opérations standard de parcours avec clé //
 //******************************************//
 // Retournent TRUE si l'opération a bien aboutie
  bool __fastcall GetFirst( EICTag tag, void* pvBuffer, void* pvKey, WORD eNewKeyID);
  bool __fastcall GetNext(  EICTag tag, void* pvBuffer, void* pvKey, WORD ePreviousKeyID);

  bool __fastcall GetEQ(   EICTag tag, void* pvBuffer, const void* pcvKey, WORD eNewKeyID);
  bool __fastcall GetGT(   EICTag tag, void* pvBuffer, const void* pcvKey, WORD eNewKeyID);
  bool __fastcall GetGTEQ( EICTag tag, void* pvBuffer, void* pcvKey, WORD eNewKeyID);

  void __fastcall InsertNew(     EICTag tag, const void* pcvBuffer, void* pvKey = NULL, WORD eNewKeyID      = K_CURRENT);
  void __fastcall UpdateCurrent( EICTag tag, const void* pcvBuffer, void* pvKey = NULL, WORD ePreviousKeyID = K_CURRENT);

  long __fastcall GetPosition( EICTag tag);  // Renvoi 0L si il n'y avait pas de position
  // Renvoi faux si lPos est invalide
  bool __fastcall GetDirect( EICTag tag, void* pvBuffer, void* pcvKey, WORD eNewKeyID, long lPos);
  __fastcall CBtrvFile();
  virtual __fastcall ~CBtrvFile();
  __property unsigned int StatusErreur = {read = m_StatusErreur};
};

#endif // #ifndef _BTRIEVE_H

